AddCSLuaFile('cl_init.lua')
AddCSLuaFile('shared.lua')
include('shared.lua')

function reset_ent()
	RunConsoleCommand("lua_reloadent_sv", "free_streamradio")
	RunConsoleCommand("lua_reloadent_cl", "free_streamradio")
end

concommand.Add("st_reset", reset_ent)

// if (not BASS) then pcall(require, "BASS") end

local EntryTable = {}
local SoundsEntries = {}
local PackTable = {}

ENT.WireDebugName = "Streamradio"

local SpectrumTableADS = {}

function findstreamfiles()
	SoundsEntries = file.Find("StreamRadio/*.txt")
	for _, FileName in pairs(SoundsEntries) do
		PackTable = util.KeyValuesToTable(file.Read("StreamRadio/" .. FileName) or {})
		table.sort(PackTable)

		for Name, Link in pairs(PackTable) do
			if (Name ~= "" and Link ~= "") then
				EntryTable[Name] = Link
			end
		end
	end
end

findstreamfiles()

local IndexPage = {}
local IndexNum = 0

for Name, _ in pairs(EntryTable) do
	IndexPage[IndexNum+1] = Name
	IndexNum = IndexNum + 1
	table.sort(IndexPage)
end

function ENT:SpawnFunction(ply, tr)
	if (not tr.Hit) then return end

	local SpawnPos = tr.HitPos + tr.HitNormal * 16
	local ent = ents.Create("free_streamradio")
	local ang = ply:GetAimVector():Angle(); ang.p = 0; ang.r = 0; ang.y = (ang.y+180) % 360
	ent:SetPos( SpawnPos )
	ent:SetAngles(ang)
	ent:SetVar("Owner",ply)
	ent:Spawn()
	ent:Activate()
	return ent
end

function ENT:Initialize()
	self.Entity:SetModel("models/props/cs_office/radio.mdl")

	self.Entity:PhysicsInit(SOLID_VPHYSICS)
	self.Entity:SetMoveType(MOVETYPE_VPHYSICS)
	self.Entity:SetSolid(SOLID_VPHYSICS)
	self.Entity:SetUseType(SIMPLE_USE)

	local phys = self.Entity:GetPhysicsObject()
	if (phys:IsValid()) then
		phys:Wake()
	end

	self:NBool("Mode", false)
	self:NString("SoundSource", "")
	self:NString("SoundName", "")
	self:NInt("Spectrum_Bars", 128 )
	self:NFloat("Volume", 100)

	self.SoundSource = ""
	self.SoundName = ""

	self.CurIndex = 1

	self:NString("Entry1", IndexPage[self.CurIndex] or "")
	self:NString("Entry2", IndexPage[self.CurIndex+1] or "")
	self:NString("Entry3", IndexPage[self.CurIndex+2] or "")
	self:NString("Entry4", IndexPage[self.CurIndex+3] or "")
	self:NInt("ActiveEntry", 0)

	if WireAddon then
		self.Inputs = WireLib.CreateSpecialInputs(self.Entity, { "Play", "Volume", "Spectrum Bars", "Stream URL"}, {"NORMAL", "NORMAL", "NORMAL", "STRING"})
		self.Outputs = WireLib.CreateSpecialOutputs( self.Entity, {"Playing", "Stream Name", "Stream URL", "Stream URLs", "Spectrum"}, {"NORMAL", "STRING", "STRING", "ARRAY", "ARRAY"})
	end
end

function ENT:Use(activator, caller)
	local Mode = self:NBool("Mode")

	local Pos = self.Entity:GetPos() + (self.Entity:GetForward() * 2.4) + (self.Entity:GetUp() * (3.7 + 3)) + (self.Entity:GetRight() * 7)
	local Ang = self.Entity:GetAngles()
	local Rot = Vector(-90,90,0)
	Ang:RotateAroundAxis(Ang:Right(), Rot.x)
	Ang:RotateAroundAxis(Ang:Up(), Rot.y)
	Ang:RotateAroundAxis(Ang:Forward(), Rot.z)

	local Cx, Cy = 0, 0
	local C1 = false

	local trace = activator:GetEyeTraceNoCursor()
	if (trace.Entity == self.Entity) then
		local HitPos = WorldToLocal(trace.HitPos, Angle(0,0,0), Pos, Ang)
		Cx = (HitPos.x / 14) * 700
		Cy = (-HitPos.y / 6) * 300
		C1 = true
	end

	if (Mode == false) then
		if (C1 and Cx > 34 and Cx < 402) then
			if (Cy > 30 and Cy < 70 and self:NString("Entry1") ~= "") then
				self:NInt("ActiveEntry", 1)
				self.SoundSource = EntryTable[IndexPage[self.CurIndex]]
				self.SoundName = IndexPage[self.CurIndex]
				self:NString("SoundSource", self.SoundSource)
				self:NString("SoundName", self.SoundName)
			elseif (Cy > 94 and Cy < 134 and self:NString("Entry2") ~= "") then
				self:NInt("ActiveEntry", 2)
				self.SoundSource = EntryTable[IndexPage[self.CurIndex+1]]
				self.SoundName = IndexPage[self.CurIndex+1]
				self:NString("SoundSource", self.SoundSource)
				self:NString("SoundName", self.SoundName)
			elseif (Cy > 159 and Cy < 199 and self:NString("Entry3") ~= "") then
				self:NInt("ActiveEntry", 3)
				self.SoundSource = EntryTable[IndexPage[self.CurIndex+2]]
				self.SoundName = IndexPage[self.CurIndex+2]
				self:NString("SoundSource", self.SoundSource)
				self:NString("SoundName", self.SoundName)
			elseif (Cy > 224 and Cy < 264 and self:NString("Entry4") ~= "") then
				self:NInt("ActiveEntry", 4)
				self.SoundSource = EntryTable[IndexPage[self.CurIndex+3]]
				self.SoundName = IndexPage[self.CurIndex+3]
				self:NString("SoundSource", self.SoundSource)
				self:NString("SoundName", self.SoundName)
			end
		end

		if (C1 and Cx > 420 and Cx < 520 and Cy > 20 and Cy < 120) then
			self.CurIndex = self.CurIndex - 2
			if (self.CurIndex < 1) then self.CurIndex = 1 end
			self:NInt("ActiveEntry", 0)
		end

		if (C1 and Cx > 420 and Cx < 520 and Cy > 180 and Cy < 280) then
			self.CurIndex = self.CurIndex + 2
			if (self.CurIndex > IndexNum - 3) then self.CurIndex = IndexNum - 3 end
			if (self.CurIndex < 1) then self.CurIndex = 1 end
			self:NInt("ActiveEntry", 0)
		end

		self:NString("Entry1", IndexPage[self.CurIndex] or "")
		self:NString("Entry2", IndexPage[self.CurIndex+1] or "")
		self:NString("Entry3", IndexPage[self.CurIndex+2] or "")
		self:NString("Entry4", IndexPage[self.CurIndex+3] or "")

		if (C1 and Cx > 520 and Cx < 680 and Cy > 20 and Cy < 280) then
			if (self:NInt("ActiveEntry") ~= 0) then
				self:NBool("Mode", true)
			end
		end
	elseif (Mode == true) then
		if (C1 and Cx > 400 and Cx < 650 and Cy > 60 and Cy < 160) then
			self:NBool("Mode", false)
		end
	end
end

function ENT:Think()
	if WireAddon then
		for i=1, 8, 1 do
			local SptaV = self:NInt(tostring(i))
			SptaV = SpectrumTableADS[i]
			//print(SpectrumTableADS[i])
		end

		local Mode = self:NBool("Mode")

		if (Mode == true) then
			ModeN = 1
		elseif (Mode == false) then
			ModeN = 0
		end

		Wire_TriggerOutput(self.Entity, "Playing", ModeN)
		Wire_TriggerOutput(self.Entity, "Stream Name", self.SoundName)
		Wire_TriggerOutput(self.Entity, "Stream URL", self.SoundSource)
		Wire_TriggerOutput(self.Entity, "Spectrum", SpectrumTableADS)
		Wire_TriggerOutput(self.Entity, "Stream URLs", EntryTable)
	end

	self.Entity:NextThink(CurTime()+0.01)
	return true
end

function ENT:OnRestore()
	Wire_Restored(self.Entity)
end

function ENT:TriggerInput(iname, value)
	if(iname == "Play") then
		if(value and value ~= 0) then
			if (self:NInt("SoundSource")) then
				self:NBool("Mode", true)
			else
				self:NBool("Mode", false)
			end
		else
			self:NBool("Mode", false)
		end
	elseif(iname == "Volume") then
		if(value and value ~= 0) then
			self:NFloat("Volume", math.Round(value))
		else
			self:NFloat("Volume", 100)
		end
	elseif(iname == "Spectrum Bars") then
		if(value and value ~= 0) then
			self:NInt("Spectrum_Bars", math.Clamp(math.Round(value), 1, 1024))
		else
			self:NInt("Spectrum_Bars", 128)
		end
	elseif(iname == "Stream URL") then
		if(value and value ~= "") then
			self.SoundSource = value
			self.SoundName = "Wire Stream URL Input"
			self:NString("SoundSource", self.SoundSource)
			self:NString("SoundName", self.SoundName)
		else
			self.SoundName = ""
			self:NString("SoundName", self.SoundName)
			self:NBool("Mode", false)
		end
	end
end